package com.jz.netthings.system.utils;

import com.jz.netthings.exception.AdscmSystemException;
import com.jz.netthings.utils.AdscmBaseUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;

/**
 * @author yyy
 * @ClassName AdscmSystemUtils
 * @Description
 * @date 2018/8/3 15:49
 */
public class AdscmSystemUtils {

    private static AdscmSystemUtils adscmSystemUtils;
    Logger logger = LoggerFactory.getLogger(getClass());


    private AdscmSystemUtils(){}

    public static AdscmSystemUtils getInstance(){
        synchronized (AdscmSystemUtils.class){
            if (adscmSystemUtils == null){
                adscmSystemUtils = new AdscmSystemUtils();
            }
            return adscmSystemUtils;
        }

    }

    /**
     * 上传文件
     * @param multiRequest
     * @return
     * @throws AdscmSystemException
     */
//    public List<String> uploadFile(CommonsMultipartFile[] files,String basePath) throws AdscmSystemException{
    public List<String> uploadFile(MultipartHttpServletRequest multiRequest, String basePath) throws AdscmSystemException{
        try{

            long  startTime=System.currentTimeMillis();

            List<String> filesPath = new ArrayList<>();

            Iterator iter = multiRequest.getFileNames();

            while(iter.hasNext()){
                //一次遍历所有文件
                MultipartFile file=multiRequest.getFile(iter.next().toString());

                String oldFileName = file.getOriginalFilename();

                if(!AdscmBaseUtils.getInstance().isNotEmpty(oldFileName,null)){
                    continue;
                }

                logger.info("开始上传文件："+oldFileName);
                long  beginOnceTime = System.currentTimeMillis();

                String suffix = oldFileName.substring(oldFileName.lastIndexOf("."));


                String newName = UUID.randomUUID().toString().replaceAll("-","");

                File f = new File(basePath);
                if (!f.exists()){
                    f.mkdirs();
                }

                String path = basePath  + newName + suffix;
                logger.info("服务器文件路径："+path);

                File newFile=new File(path);
                file.transferTo(newFile);

                logger.info("上传文件："+oldFileName+" 结束，耗时【"+(System.currentTimeMillis() - beginOnceTime)+"】毫秒...");
                filesPath.add(path);

            }

            long  endTime=System.currentTimeMillis();
            logger.info("所有文件上传结束，耗时【"+(endTime - startTime)+"】毫秒...");
            return filesPath;

        }catch (Exception e){
            throw new AdscmSystemException("图片上传失败："+e.getMessage());
        }
    }

    /**
     * 上传文件，不重新生成文件名
     * @param multiRequest
     * @return
     * @throws AdscmSystemException
     */
//    public List<String> uploadFile(CommonsMultipartFile[] files,String basePath) throws AdscmSystemException{
    public List<String> uploadFileNoNewName(MultipartHttpServletRequest multiRequest, String basePath) throws AdscmSystemException{
        try{

            long  startTime=System.currentTimeMillis();

            List<String> filesPath = new ArrayList<>();

            Iterator iter = multiRequest.getFileNames();

            while(iter.hasNext()){
                //一次遍历所有文件
                MultipartFile file=multiRequest.getFile(iter.next().toString());

                String oldFileName = file.getOriginalFilename();

                if(!AdscmBaseUtils.getInstance().isNotEmpty(oldFileName,null)){
                    continue;
                }

                logger.info("开始上传文件："+oldFileName);
                long  beginOnceTime = System.currentTimeMillis();


                File f = new File(basePath);
                if (!f.exists()){
                    f.mkdirs();
                }

                String path = basePath  + oldFileName;
                logger.info("服务器文件路径："+path);

                File newFile=new File(path);
                file.transferTo(newFile);

                logger.info("上传文件："+oldFileName+" 结束，耗时【"+(System.currentTimeMillis() - beginOnceTime)+"】毫秒...");
                filesPath.add(path);

            }

            long  endTime=System.currentTimeMillis();
            logger.info("所有文件上传结束，耗时【"+(endTime - startTime)+"】毫秒...");
            return filesPath;

        }catch (Exception e){
            throw new AdscmSystemException("图片上传失败："+e.getMessage());
        }
    }

    /**
     * 下载文件，根据文件路径
     * @param fileName 文件路径 + 文件名，例如：D:\ABC\ABC.pdf
     * @param response
     */
    public void downloadFile(String fileName,HttpServletResponse response) throws AdscmSystemException{

        logger.info("开始下载文件："+fileName);
        if (fileName != null) {
            File file = new File(fileName);
            if (file.exists()) {
                fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
                response.setHeader("content-type", "application/octet-stream;charset=UTF-8");
                response.setContentType("application/octet-stream;charset=UTF-8");
                try {
                    response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName,"UTF-8"));
                } catch (UnsupportedEncodingException e) {
                    throw new AdscmSystemException("文件下载失败："+e.getMessage());
                }

                byte[] buffer = new byte[1024];
                FileInputStream fis = null;
                BufferedInputStream bis = null;
                try {
                    fis = new FileInputStream(file);
                    bis = new BufferedInputStream(fis);
                    OutputStream os = response.getOutputStream();
                    int i = bis.read(buffer);
                    while (i != -1) {
                        os.write(buffer, 0, i);
                        i = bis.read(buffer);
                    }
                    logger.info("下载文件【"+fileName+"】成功...");
                } catch (Exception e) {
                    throw new AdscmSystemException("文件下载失败："+e.getMessage());
                } finally {
                    if (bis != null) {
                        try {
                            bis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fis != null) {
                        try {
                            fis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    /**
     * 输出文件
     * @param filePath
     * @param response
     * @throws AdscmSystemException
     */
    public void writeFile(String filePath,HttpServletResponse response) throws AdscmSystemException{
        logger.info("输出文件【"+filePath+"】开始...");
        File file = new File(filePath);
        byte[] data = null;
        FileInputStream in = null;

        try{

            response.setDateHeader("expries", -1);
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Pragma", "no-cache");

            in = new FileInputStream(file);

            data = new byte[in.available()];
            in.read(data);
            response.getOutputStream().write(data);
            logger.info("输出文件【"+filePath+"】成功...");
        }catch (Exception e){
            logger.error("输出文件【"+filePath+"】异常...");
            throw new AdscmSystemException("输出文件异常："+e.getMessage());
        }finally {
            if (in != null){
                try {
                    in.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }
    /**
     * 输出视频文件
     * @param filePath
     * @param response
     * @throws AdscmSystemException
     */
    public void writeVideoFile(String filePath,HttpServletResponse response){

        try{
            this.writeFile(filePath,response);
        }catch (Exception e){
            logger.error(e.getMessage());
        }
    }


    /**
     * 根据文件地址，获取文件的二进制数据
     * @param filePath
     * @return
     * @throws AdscmSystemException
     */
    public byte[] getFileBytes(String filePath) throws AdscmSystemException{

        return AdscmBaseUtils.getInstance().getFileBytes(filePath);
    }



}
